package com.luoye_lj.dogcontroller.util;

import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.util.Log;

import androidx.core.app.ActivityCompat;

import java.util.UUID;

public class BleGattConnector {
    private static final String TAG = "BleGattConnector";

    // 一些常用的UUID（根据你的设备修改）
    private static final UUID SERVICE_UUID = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb");
    private static final UUID CHARACTERISTIC_UUID_WRITE = UUID.fromString("0000fff2-0000-1000-8000-00805f9b34fb");
    private static final UUID CHARACTERISTIC_UUID_NOTIFY = UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb");
    private static final UUID CHARACTERISTIC_UUID_READ = UUID.fromString("0000fff3-0000-1000-8000-00805f9b34fb");
    private static final UUID CLIENT_CHARACTERISTIC_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

    private BluetoothGatt bluetoothGatt;

    private BluetoothGattCharacteristic writeCharacteristic;
    private BluetoothGattCharacteristic readCharacteristic;

    private final Handler handler = new Handler();

    public interface BleConnectionListener {
        void onConnected();

        void onDisconnected();

        void onServicesDiscovered();

        void onDataReceived(byte[] data);

        void onError(String errorMessage);
    }

    private final Context context;
    private final BluetoothDevice targetDevice;
    private final BleConnectionListener connectionListener;

    public BleGattConnector(Context context, BluetoothDevice targetDevice, BleConnectionListener connectionListener) {
        this.context = context;
        this.targetDevice = targetDevice;
        this.connectionListener = connectionListener;
    }

    // 连接到设备
    @SuppressLint("MissingPermission")
    public void connect() {
        if (targetDevice == null) {
            connectionListener.onError("设备为空");
            return;
        }

        // 如果已有连接，先断开
        if (bluetoothGatt != null) {
            bluetoothGatt.close();
            bluetoothGatt = null;
        }

        // 连接到GATT服务器
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            bluetoothGatt = targetDevice.connectGatt(context, false, gattCallback, BluetoothDevice.TRANSPORT_LE);
        } else {
            bluetoothGatt = targetDevice.connectGatt(context, false, gattCallback);
        }
    }

    // 断开连接
    @SuppressLint("MissingPermission")
    public void disconnect() {
        if (bluetoothGatt != null) {
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
            bluetoothGatt = null;
        }
        handler.removeCallbacksAndMessages(null);
    }

    // 读取特征值
    @SuppressLint("MissingPermission")
    public void readData() {
        if (bluetoothGatt == null || readCharacteristic == null) {
            return;
        }
        bluetoothGatt.readCharacteristic(readCharacteristic);
    }

    // 写入特征值
    @SuppressLint("MissingPermission")
    public void writeData(byte[] data) {
        if (bluetoothGatt == null || writeCharacteristic == null) {
            return;
        }
        writeCharacteristic.setValue(data);
        bluetoothGatt.writeCharacteristic(writeCharacteristic);
    }

    // 工具方法：字节数组转十六进制字符串
    public String bytesToHex(byte[] bytes) {
        if (bytes == null) return "null";
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString();
    }


    // GATT回调 - 处理连接状态、服务发现、数据读写等事件
    private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
        @SuppressLint("MissingPermission")
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);

            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    // 连接成功，开始发现服务
                    Log.i(TAG, "已连接到GATT服务器");
                    handler.post(() -> {
                        if (connectionListener != null) {
                            connectionListener.onConnected();
                        }
                    });

                    // 发现服务
                    bluetoothGatt.discoverServices();
                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                    // 连接断开
                    Log.i(TAG, "与GATT服务器断开连接");
                    handler.post(() -> {
                        if (connectionListener != null) {
                            connectionListener.onDisconnected();
                        }
                    });
                }
            } else {
                // 连接失败
                Log.e(TAG, "连接状态错误: " + status);
                handler.post(() -> {
                    if (connectionListener != null) {
                        connectionListener.onError("连接失败，状态码: " + status);
                    }
                });
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);

            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.i(TAG, "服务发现成功");

                // 获取目标服务
                BluetoothGattService service = gatt.getService(SERVICE_UUID);
                if (service != null) {
                    // 获取特征
                    BluetoothGattCharacteristic notifyCharacteristic = service.getCharacteristic(CHARACTERISTIC_UUID_NOTIFY);
                    writeCharacteristic = service.getCharacteristic(CHARACTERISTIC_UUID_WRITE);
                    readCharacteristic = service.getCharacteristic(CHARACTERISTIC_UUID_READ);

                    // 启用通知
                    if (notifyCharacteristic != null) {
                        enableNotifications(notifyCharacteristic, true);
                    }

                    handler.post(() -> {
                        if (connectionListener != null) {
                            connectionListener.onServicesDiscovered();
                        }
                    });
                } else {
                    handler.post(() -> {
                        if (connectionListener != null) {
                            connectionListener.onError("未找到目标服务");
                        }
                    });
                }
            } else {
                Log.e(TAG, "服务发现失败: " + status);
                handler.post(() -> {
                    if (connectionListener != null) {
                        connectionListener.onError("服务发现失败，状态码: " + status);
                    }
                });
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);

            if (status == BluetoothGatt.GATT_SUCCESS) {
                byte[] data = characteristic.getValue();
                Log.i(TAG, "读取特征值成功: " + bytesToHex(data));
                handler.post(() -> {
                    if (connectionListener != null) {
                        connectionListener.onDataReceived(data);
                    }
                });
            } else {
                Log.e(TAG, "读取特征值失败: " + status);
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);

            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.i(TAG, "写入特征值成功");
            } else {
                Log.e(TAG, "写入特征值失败: " + status);
                handler.post(() -> {
                    if (connectionListener != null) {
                        connectionListener.onError("写入失败，状态码: " + status);
                    }
                });
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);

            // 接收到通知数据
            byte[] data = characteristic.getValue();
            Log.i(TAG, "收到通知数据: " + bytesToHex(data));
            handler.post(() -> {
                if (connectionListener != null) {
                    connectionListener.onDataReceived(data);
                }
            });
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);

            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.i(TAG, "描述符写入成功");
            } else {
                Log.e(TAG, "描述符写入失败: " + status);
            }
        }

        // 启用或禁用特征通知
        public void enableNotifications(BluetoothGattCharacteristic characteristic, boolean enable) {
            if (bluetoothGatt == null || characteristic == null) {
                return;
            }

            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }

            // 设置特征的通知属性
            bluetoothGatt.setCharacteristicNotification(characteristic, enable);

            // 写入客户端特征配置描述符以启用通知
            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
            if (descriptor != null) {
                if (enable) {
                    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                } else {
                    descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
                }
                bluetoothGatt.writeDescriptor(descriptor);
            }
        }
    };
}
